package Tipos;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Stock es la variable global que comparten los panaderos
 * en cada panaderia y su acceso debe estar restringido 
 * para evitar valores inconsistentes de la cantidad de
 * panes que se poseen para la venta.
 */
public class Stock {
    private int stockFisico;   //corresponde al actual
    private int stockTemporal; //corresponde al valor del stock durante todo el proceso del commit
    private boolean valeTemporal; //informa si el valor temporal es valido o no
    private boolean accesible;  // actua como variable para el semaforo indicando si se puede o no acceder a la informacion
    private boolean comenzar; //espera que se conecten las 5 panaderias al servidor para poder comenzar con la venta de panes

    public Stock() {
        this.stockFisico = 0;
        this.stockTemporal = 0;
        this.valeTemporal = false;
        this.accesible = true;
        this.comenzar = false;
    }

    public Stock(int stockFisico) {
        this.stockFisico = stockFisico;
        this.stockTemporal = 0;
        this.valeTemporal = false;
        this.accesible = true;
        this.comenzar = false;
    }
    
    public synchronized void comenzar(){
        //System.out.println("comenzar");
        while (!accesible){
            try {
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(Stock.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        accesible = false;
        comenzar = true;
        accesible = true;
        //System.out.println("comenzado");
        notifyAll();
    }
    
    public synchronized int getStock(){
        while (!accesible || !comenzar){
            try {
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(Stock.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        accesible = false;
        int devolver;
        if(valeTemporal)
            devolver = stockTemporal;
        else 
            devolver = stockFisico;
        accesible = true;
        notifyAll();
        return devolver;
    }
    
    public synchronized boolean prestar(int venta){
        while (!accesible || valeTemporal || !comenzar){
            try {
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(Stock.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        accesible = false;
        if(stockFisico - venta >= 0){
            stockTemporal = stockFisico - venta;
            valeTemporal = true;
            accesible = true;
            notifyAll();
            return true;
        }else{
            accesible = true;
            notifyAll();
            return false;
        }
                
    }
    
    public synchronized void confirmarPrestamo(){
        while (!accesible || !comenzar){
            try {
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(Stock.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        accesible = false;
        if(valeTemporal){
            stockFisico = stockTemporal;
            valeTemporal = false;
        }else{
            System.out.println("Confirmar prestamo-----> No vale el valor temporal");
        }
        accesible = true;
        notifyAll();
    }
    
    public synchronized void deshacerPrestamo(){
        while (!accesible || !comenzar){
            try {
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(Stock.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        accesible = false;
        valeTemporal = false;
        accesible = true;
        notifyAll();
    }
    
    public synchronized boolean vender(int venta){
        while (!accesible || valeTemporal || !comenzar){
            try {
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(Stock.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        accesible = false;
        if(stockFisico - venta >= 0){
            stockFisico = stockFisico - venta;
            accesible = true;
            notifyAll();
            return true;
        }else{
            accesible = true;
            notifyAll();
            return false;
        }
        
    }
    
    public synchronized boolean atender(){
        while (!accesible || (valeTemporal && stockTemporal == 0) || !comenzar){
            try {
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(Stock.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        accesible = false;
        if (stockFisico == 0 ){
            accesible = true;
            notifyAll();
            return false;
        }else {
            accesible = true;
            notifyAll();
            return true;
        }
            
        
    }
    
}
